package v2ray

import (
	"gitee.com/Luna-CY/hui-hui/internal/interface/application"
	"gitee.com/Luna-CY/hui-hui/server/http/response"
	"github.com/gin-gonic/gin"
)

type GetConfigResponse struct {
	Inbounds  []Bound `json:"inbounds" validate:"required"`  // 入站协议列表
	Outbounds []Bound `json:"outbounds" validate:"required"` // 出站协议列表
}

type Bound struct {
	Id       string `json:"id" validate:"required"`       // 配置对象ID
	Tag      string `json:"tag" validate:"required"`      // 自定义标识，不为空时唯一
	Protocol string `json:"protocol" validate:"required"` // 协议类型，指定哪一种协议配置有效
	Inbound  struct {
		Listen string `json:"listen" validate:"required"` // 监听地址
		Port   int    `json:"port" validate:"required"`   // 监听端口
	} `json:"inbound"` // 入站协议的私有配置，入站协议有效
	Outbound struct {
		SendThrough string `json:"send_through" validate:"required"` // 用于发送数据的IP地址，默认为0.0.0.0
	} `json:"outbound"` // 出站协议的私有配置，出站协议有效
	StreamSettings struct {
		Enable      bool   `json:"enable" validate:"required"` // 是否启用此项配置
		Network     string `json:"network" validate:"required"`
		TlsSettings struct {
			ClientOnly bool   `json:"client_only" validate:"required"` // 是否仅客户端有效
			Security   string `json:"security" validate:"required"`    // 安全类型，none或tls，默认为none
			ServerName string `json:"server_name" validate:"required"` // TLS域名
		} `json:"tls_settings" validate:"required"`
		TcpSettings struct {
			Header struct {
				Type string `json:"type" validate:"required"` // 默认为none
			} `json:"header" validate:"required"`
		} `json:"tcp_settings" validate:"required"`
		KcpSettings struct {
			Mtu              int  `json:"mtu" validate:"required"`               // 传输单元配置，允许的范围为576-1460，默认为1350
			Tti              int  `json:"tti" validate:"required"`               // 传输频率，允许的范围为1-100，默认为50
			UplinkCapacity   *int `json:"uplink_capacity" validate:"required"`   // 上行带宽限制，单位MB，默认值为5，允许设置为0
			DownlinkCapacity *int `json:"downlink_capacity" validate:"required"` // 下行带宽限制，单位MB，默认值为20，允许设置为0
			Congestion       bool `json:"congestion" validate:"required"`        // 是否启用拥塞控制
			ReadBufferSize   int  `json:"read_buffer_size" validate:"required"`  // 单个连接的读缓冲区大小，单位MB，默认为2
			WriteBufferSize  int  `json:"write_buffer_size" validate:"required"` // 单个连接的写缓冲区大小，单位MB，默认为2
			Header           struct {
				Type string `json:"type" validate:"required"` // 伪装类型，默认为none，可选: none/srtp/utp/wechat-video/dtls/wireguard
			} `json:"header" validate:"required"` // 头信息配置
		} `json:"kcp_settings" validate:"required"`
		WebsocketSettings struct {
			Path    string            `json:"path" validate:"required"`    // 默认值为/
			Headers map[string]string `json:"headers" validate:"required"` // 头信息，KEY/VALUE对
		} `json:"websocket_settings" validate:"required"`
		DomainSocketSettings struct {
			Path string `json:"path" validate:"required"` // 一个文件路径，V2ray启动前，此文件必须不存在，但路径必须有效(文件夹有效)
		} `json:"domain_socket_settings" validate:"required"`
		Http2Settings struct {
			Host []string `json:"host" validate:"required"`
			Path string   `json:"path" validate:"required"` // 默认值为/
		} `json:"http2_settings" validate:"required"`
		QuicSettings struct {
			Security string `json:"security" validate:"required"` // 加密类型，默认为none，可选: none/aes-128-gcm/chacha20-poly1305
			Key      string `json:"key" validate:"required"`      // 加密类型不为none时用于加密数据
			Header   struct {
				Type string `json:"type" validate:"required"` // 伪装类型，默认为none，可选: none/srtp/utp/wechat-video/dtls/wireguard
			} `json:"header" validate:"required"` // 头信息配置
		} `json:"quic_settings" validate:"required"`
	} `json:"stream_settings" validate:"required"` // 传输方式配置
	Freedom struct {
		DomainStrategy string `json:"domain_strategy" validate:"required"` // 解析模式，默认AsIs，可选: AsIs|UseIP|UseIPv4|UseIPV6
		Redirect       string `json:"redirect" validate:"required"`        // 强制转发的目标地址，可以为空
		UserLevel      int    `json:"user_level" validate:"required"`      // 用户等级
	} `json:"freedom" validate:"required"` // Freedom出站协议
	VMess struct {
		Inbound struct {
			Clients                   []VMessClient `json:"clients" validate:"required"`                     // 用户列表
			DisableInsecureEncryption bool          `json:"disable_insecure_encryption" validate:"required"` // 是否禁用不安全的加密协议，默认为false
		} `json:"inbound" validate:"required"` // 入站配置
		Outbound struct {
			Vnext []VMessVnext `json:"vnext" validate:"required"` // 服务器配置
		} `json:"outbound" validate:"required"` // 出站配置
	} `json:"vmess" validate:"required"` // VMess协议，区分入站与出站配置
}

type BaseAccount struct {
	Username string `json:"username" validate:"required"` // 用户名
	Password string `json:"password" validate:"required"` // 密码
	Level    int    `json:"level" validate:"required"`    // 用户等级，默认为0，仅Socks协议的Outbound配置内有效
}

type HttpServer struct {
	Address string        `json:"address"` // 服务器地址，不能为空
	Port    int           `json:"port"`    // 服务器端口，不能为空
	Users   []BaseAccount `json:"users"`   // 用户列表，可以为空，为空时不进行身份验证
}

type ShadowSocksServer struct {
	Email    string `json:"email" validate:"required"`    // 邮件地址，可为空
	Address  string `json:"address" validate:"required"`  // 服务器地址，不能为空
	Port     int    `json:"port" validate:"required"`     // 服务器端口，不能为空
	Method   string `json:"method" validate:"required"`   // 加密方式，此项不能为空，可选:aes-256-cfb/aes-128-cfb/chacha20/chacha20-ietf/aes-256-gcm/aes-128-gcm/chacha20-poly1305
	Password string `json:"password" validate:"required"` // 验证密码，此项不能为空
	OTA      bool   `json:"ota" validate:"required"`      // 是否强制开启OTA，默认为false
	Level    int    `json:"level" validate:"required"`    // 用户等级
}

type SocksServer struct {
	Address string        `json:"address" validate:"required"` // 服务器地址，不能为空
	Port    int           `json:"port" validate:"required"`    // 服务器端口，不能为空
	Users   []BaseAccount `json:"users" validate:"required"`   // 用户列表，可以为空，为空时不进行身份验证
}

type VMessClient struct {
	Id       string `json:"id" validate:"required"`       // ID
	Level    int    `json:"level" validate:"required"`    // 用户等级，默认为0
	Email    string `json:"email" validate:"required"`    // 邮件地址，可为空
	Security string `json:"security" validate:"required"` // 加密方式，仅出站配置有效，默认auto，不支持更改
}

type VMessVnext struct {
	Address string        `json:"address" validate:"required"` // 服务器地址，不能为空
	Port    int           `json:"port" validate:"required"`    // 服务器端口，不能为空
	Users   []VMessClient `json:"users" validate:"required"`   // 用户列表，可以为空，为空时不进行身份验证
}

func (cls *V2ray) GetConfig(_ *gin.Context) (int, any, error) {
	var config = cls.v2ray.GetConfig()

	var res = GetConfigResponse{}
	res.Inbounds = make([]Bound, 0)
	for _, bound := range config.Inbounds {
		res.Inbounds = append(res.Inbounds, cls.bound(bound))
	}

	res.Outbounds = make([]Bound, 0)

	for _, bound := range config.Outbounds {
		res.Outbounds = append(res.Outbounds, cls.bound(bound))
	}

	return response.Ok, res, nil
}

func (cls *V2ray) bound(src *application.V2rayBound) Bound {
	var bound = Bound{}
	bound.Id = src.Id
	bound.Tag = src.Tag
	bound.Protocol = src.Protocol
	bound.Inbound.Listen = src.Inbound.Listen
	bound.Inbound.Port = src.Inbound.Port
	bound.Outbound.SendThrough = src.Outbound.SendThrough

	bound.StreamSettings.Enable = src.StreamSettings.Enable
	bound.StreamSettings.TlsSettings.ClientOnly = src.StreamSettings.TlsSettings.ClientOnly
	bound.StreamSettings.TlsSettings.Security = src.StreamSettings.TlsSettings.Security
	bound.StreamSettings.TlsSettings.ServerName = src.StreamSettings.TlsSettings.ServerName
	bound.StreamSettings.Network = string(src.StreamSettings.Network)
	bound.StreamSettings.TcpSettings.Header.Type = src.StreamSettings.TcpSettings.Header.Type

	bound.StreamSettings.KcpSettings.Mtu = src.StreamSettings.KcpSettings.Mtu
	bound.StreamSettings.KcpSettings.Tti = src.StreamSettings.KcpSettings.Tti
	bound.StreamSettings.KcpSettings.UplinkCapacity = src.StreamSettings.KcpSettings.UplinkCapacity
	bound.StreamSettings.KcpSettings.DownlinkCapacity = src.StreamSettings.KcpSettings.DownlinkCapacity
	bound.StreamSettings.KcpSettings.ReadBufferSize = src.StreamSettings.KcpSettings.ReadBufferSize
	bound.StreamSettings.KcpSettings.WriteBufferSize = src.StreamSettings.KcpSettings.WriteBufferSize
	bound.StreamSettings.KcpSettings.Congestion = src.StreamSettings.KcpSettings.Congestion
	bound.StreamSettings.KcpSettings.Header.Type = src.StreamSettings.KcpSettings.Header.Type

	bound.StreamSettings.WebsocketSettings.Path = src.StreamSettings.WebsocketSettings.Path
	bound.StreamSettings.WebsocketSettings.Headers = src.StreamSettings.WebsocketSettings.Headers
	bound.StreamSettings.DomainSocketSettings.Path = src.StreamSettings.DomainSocketSettings.Path

	bound.StreamSettings.Http2Settings.Host = src.StreamSettings.Http2Settings.Host
	bound.StreamSettings.Http2Settings.Path = src.StreamSettings.Http2Settings.Path
	bound.StreamSettings.QuicSettings.Security = src.StreamSettings.QuicSettings.Security
	bound.StreamSettings.QuicSettings.Key = src.StreamSettings.QuicSettings.Key
	bound.StreamSettings.QuicSettings.Header.Type = src.StreamSettings.QuicSettings.Header.Type

	bound.Freedom.DomainStrategy = string(src.Freedom.DomainStrategy)
	bound.Freedom.Redirect = src.Freedom.Redirect
	bound.Freedom.UserLevel = src.Freedom.UserLevel

	bound.VMess.Inbound.DisableInsecureEncryption = src.VMess.Inbound.DisableInsecureEncryption
	bound.VMess.Inbound.Clients = make([]VMessClient, 0)
	for _, client := range src.VMess.Inbound.Clients {
		bound.VMess.Inbound.Clients = append(bound.VMess.Inbound.Clients, VMessClient{Id: client.Id, Level: client.Level, Email: client.Email, Security: client.Security})
	}
	bound.VMess.Outbound.Vnext = make([]VMessVnext, 0)
	for _, next := range src.VMess.Outbound.Vnext {
		var item = VMessVnext{Address: next.Address, Port: next.Port, Users: make([]VMessClient, 0)}
		for _, client := range next.Users {
			item.Users = append(item.Users, VMessClient{Id: client.Id, Level: client.Level, Email: client.Email, Security: client.Security})
		}

		bound.VMess.Outbound.Vnext = append(bound.VMess.Outbound.Vnext, item)
	}

	return bound
}
